<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 浏览器不识别代码，首先形成一个domTree
        //         domTree  符合深度优先原则
        //             <html>
        // head                     body
        // title   meta        div   span   strong
        //                                    em

        // 浏览器看到img,iframe等资源就直接挂到dom树上，不用等他下载完成(下载完成肯定在解析之后)
        // domTree形成完等cssTree形成
        // domTree + cssTree = randerTree(渲染，绘制)

        // reflow  重排(效率低，要尽量避免)   dom节点的删除，添加
        //                        dom节点的宽高变化，位置变化，display: none-->block
        //                        offsetWidth  offsetLeft
        // repaint   重绘(浪费的效率较少)

        //        异步加载js
        // js加载的缺点：加载工具方法没必要阻塞文档，过得js加载会影响页面效率
        // 一旦网速不好，那么整个网站将等待js加载而不进行后续渲染等工作。

        // 有些工具方法需要按需加载，用到再加载，不用不加载

        // JavaScript异步加载的三种方案
        //    1.defer异步加载，但要等到DOM文档全部解析完才会被执行，只有IE能用，也可以将代码写到内部
        //    2.async异步加载，加载完就执行，async只能加载外部脚本，不能把js写在script标签里面(W3C标准)



        // 封装一个解决异步加载兼容问题的函数
        function loadScript(url, callback) {
            var script = document.createElement('script');
            script.type = 'text/javascript';
            if (script.readyState) {
                script.onreadystatechange = function() {
                    if (script.readyState == 'compleate' || script.readyState == 'loaded') {
                        callback(); // 回调函数 执行
                    }
                }
            } else {
                script.onload = function() {
                    callback(); // 回调函数 执行
                }
            }
            script.src = url; //执行到这一步开始下载地址里的东西
            document.head.appendChild(script);
        }
        loadScript('xxx.js', function() {
            test(); // 直接执行的话页面中根本没有定义这个函数,会报错
            // 在匿名函数中执行相当于一个函数引用,不会去解析里面的代码
        });
    </script>
    <script type="text/javascript">
        //    1.2执行时也不阻塞页面
        //    3.创建script，插入到DOM中，加载完毕后callBack，
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'zzz.js'; //执行到这一步开始下载地址里的东西


        if (script.readyState) {
            script.onreadystatechange = function() {
                if (script.readyState == 'compleate' || script.readyState == 'loaded') {
                    // 执行
                }
            }
        } else {
            script.onload = function() {
                // 执行
            }
        }




        document.head.appendChild(script); //当把标签插入页面里面去的时候才会执行
        script.onload = function() {
            // xxxxx   （下载完才能执行）
        }

        // IE的script上面没有onload
        // IE专属：状态码->script.readyState
        script.readyState = 'loading';
        //会根据script加载的进度动态改变里面的值
        // 如果加载完的话，会把里面的值改成，compleate/loaded
        script.onreadystatechange = function() {
            if (script.readyState == 'compleate' || script.readyState == 'loaded') {
                // 执行
            }
        }
    </script>

    <script src="xxx.js" defer="defer">
        // 加defer变成异步加载
        // 凡是属性名等于属性值的只写属性名就行，但是最好写全
    </script>

    <script src="yyy.js" async="async">
        // asychronous  异步
        // asychronous javascript and xml  ---->  ajax
    </script>
</body>

</html>